package com.hs.core.db;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import javax.servlet.ServletContext;
import javax.sql.DataSource;

import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.hs.Environment;
import com.hs.core.model.BlobObj;
import com.hs.core.model.TextObj;
import com.hs.log.HsLogger;

 



/**
 * 
 * Title:文件所属模块--数据库操作,增删改查
 * Description：数据库操作类，需要context获得连接池才能使用
 *              
 * @author shiliang
 * 
 */
public class DBOperator{
	/**
	 * Logger for this class
	 */
	private static final HsLogger logger = HsLogger.getLogger(DBOperator.class.getName());
	
	private static DataSource dboDataSource = null;
	private XmlBeanFactory factory = null;
	private JdbcTemplate jdbcTemplate ;
	public DBOperator(){
//		if(dboDataSource == null){
//			String resPath = InitSystem.getCh_Props(Constants.PROJECT_ABS_PATH)
//								+"\\WEB-INF\\Classes\\applicationContext.xml";
//			
//			FileSystemResource res = new FileSystemResource(resPath);
//			factory = new XmlBeanFactory(res);
//			dboDataSource = (DataSource)factory.getBean("dataSource");
//			
//			setDataSource(dboDataSource);
//		}
	}
	public DBOperator(ServletContext context){
		try {
			init(context);
		} catch (Exception e) {
			e.printStackTrace();
		} 
	}
	 public DBOperator(DataSource dboDataSource){
		 if(null != dboDataSource)
			 this.dboDataSource = dboDataSource;
	}
	
	/**
	 * 
	 * 功能: 使用上下文中的连接池
	 * 作者: shiliang
	 * 创建日期:2007-4-5
	 * @param context
	 */
	public void init(ServletContext context){
		if(dboDataSource == null){
			WebApplicationContext wac = WebApplicationContextUtils
													.getRequiredWebApplicationContext(context);
			setDataSource((DataSource)wac.getBean("dataSource"));
		}
	}
	/**
	 * 
	 * 功能: (回调)从数据库取出一个BLob对象，要求sql的？和params的内容对应
	 * 作者: shiliang
	 * 创建日期:2007-4-7
	 * @param sql
	 * @param params
	 * @return BlobObj是包含blob数据的对象，data是byte数组
	 */
	public BlobObj getBlob(String sql, Object[] params){
		if(sql == null || sql.length() == 0 )
			return new BlobObj();
		
		jdbcTemplate = new JdbcTemplate(dboDataSource);
		
		RowMapper mapper = new RowMapper(){
			public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
				BlobObj blobObj = new BlobObj();
				
				InputStream is = rs.getBlob(1).getBinaryStream();
				
				try {
					byte[] data = new byte[1024];
					String fileStr = Environment.PROP_TEMP_FILE; 
					File file = new File(fileStr);
					FileOutputStream fos = new FileOutputStream(file);
					int len = 0;
					while((len = is.read(data)) != -1){
						fos.write(data, 0, len);
						
					}
					fos.close();
					FileInputStream fis = new FileInputStream(file);
					
					byte[] data2 = new byte[fis.available()];
					fis.read(data2);
					
					fis.close();
					file.delete();
					blobObj.setData(data2);
				} catch (IOException e) {
					e.printStackTrace();
				}
				
//				blobObj.setData(rs.getBytes(1));
				
				return blobObj;
			}
		};
		Object blob = jdbcTemplate.queryForObject(sql, params,mapper);
		
		return (BlobObj)blob;
	}
	/**
	 * 返回一个数据库连接
	 * 需要用完后显式的关闭
	 * @return
	 */
	public Connection getConnection(){
		
		try {
			return jdbcTemplate.getDataSource().getConnection();
		} catch (SQLException e) {
			
			e.printStackTrace();
			return null;
		}
	}
	/**
	 * 
	 * 功能: (回调)从数据库取出一个CLob对象，要求sql的？和params的内容对应
	 * 作者: shiliang
	 * 创建日期:2007-4-7
	 * @param sql
	 * @param params
	 * @return TextObj是包含blob数据的对象，data是byte数组
	 */
	public TextObj getClob(String sql, Object[] params){
		if(sql == null || sql.length() == 0 )
			return new TextObj();
		
		jdbcTemplate = new JdbcTemplate(dboDataSource);
		
		RowMapper mapper = new RowMapper(){
			public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
				TextObj clobObj = new TextObj();
				
				try {
					clobObj.setData(new String(rs.getBytes(1),"utf-8"));
				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
				}
				
				return clobObj;
			}
		};
		Object blob = jdbcTemplate.queryForObject(sql, params,mapper);
		
		return (TextObj)blob;
	}
	/**
	 * 
	 * 功能: 执行sql查询，list的每个元素是一行（Map）
	 * 作者: shiliang
	 * 创建日期:2007-4-4
	 * @param sql    查询sql
	 * @param params 参数
	 * @return
	 */
	public List select(String sql , Object[] params){	
		jdbcTemplate = new JdbcTemplate(dboDataSource);
		
		logger.info("SQL=="+sql+" params="+params);
		List list = jdbcTemplate.queryForList(sql,params);
		
		return list;
	}
	
	
	
	public Object getBigObject(){
		
		return null;
	}
	
	/**
	 * 
	 * 功能: 增删改数据，主要处理大对象blob，clob
	 * 作者: shiliang
	 * 创建日期:2007-4-6
	 * @param sql
	 * @param data
	 * @return -1表示失败，0表示没有更新，大于0表示更新数据
	 */
	public int update(String sql , Object[] data){
		if(sql == null || sql.length() == 0 )
			return -1;
		logger.info("SQL=="+sql+" params="+data);
		int result = 0;
		jdbcTemplate = new JdbcTemplate(dboDataSource);
		jdbcTemplate.update(sql, data);
		return result;
	}
	
	public void setDataSource(DataSource dataSource) {
		dboDataSource = dataSource;
	}
	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}
	
	
}
